/**
 * JCuPupw - Modern Modal & Toast Notification System
 * Version: 2.1.0
 * Author: ByUsi-link
 * GitHub: https://github.com/ByUsi-link/JCuPupw
 * License: MIT
 */

class JCuPupw {
    static instances = new Map();
    static defaultConfig = {
        title: '提示',
        content: '默认内容',
        buttons: [{ text: '确定', action: () => {} }],
        size: 'medium',
        animation: 'fade',
        draggable: false,
        closable: true,
        backdrop: true,
        onOpen: null,
        onClose: null,
        form: null,
        className: '',
        lang: 'zh-CN',
        theme: 'default'
    };

    static lang = {
        'zh-CN': { confirm: '确定', cancel: '取消', close: '关闭' },
        'en-US': { confirm: 'OK', cancel: 'Cancel', close: 'Close' },
        'ja-JP': { confirm: '確認', cancel: 'キャンセル', close: '閉じる' }
    };

    constructor(selector = '#jcModal', config = {}) {
        this.config = { ...JCuPupw.defaultConfig, ...config };
        this.modal = typeof selector === 'string' ? document.querySelector(selector) : selector;
        this.isOpen = false;
        this.isDragging = false;
        this.dragStartX = 0;
        this.dragStartY = 0;
        this.dragOffsetX = 0;
        this.dragOffsetY = 0;
        this.events = {};
        this.id = Math.random().toString(36).substr(2, 9);
        
        if (!this.modal) this.createModal();
        this.init();
        JCuPupw.instances.set(this.id, this);
    }

    createModal() {
        this.modal = document.createElement('div');
        this.modal.className = 'jc-modal';
        this.modal.id = 'jcModal-' + this.id;
        this.modal.setAttribute('aria-hidden', 'true');
        this.modal.setAttribute('role', 'dialog');
        this.modal.innerHTML = `
            <div class="jc-modal__overlay"></div>
            <div class="jc-modal__container">
                <button class="jc-modal__close" aria-label="${JCuPupw.lang[this.config.lang].close}">&times;</button>
                <h2 class="jc-modal__title" id="modalTitle-${this.id}">${this.config.title}</h2>
                <div class="jc-modal__content" id="modalContent-${this.id}">${this.config.content}</div>
                <div class="jc-modal__loading">
                    <div class="jc-spinner"></div>
                </div>
                <div class="jc-modal__actions" id="modalButtons-${this.id}"></div>
            </div>
        `;
        document.body.appendChild(this.modal);
    }

    init() {
        this.modalTitle = this.modal.querySelector(`#modalTitle-${this.id}`) || this.modal.querySelector('.jc-modal__title');
        this.modalContent = this.modal.querySelector(`#modalContent-${this.id}`) || this.modal.querySelector('.jc-modal__content');
        this.modalButtons = this.modal.querySelector(`#modalButtons-${this.id}`) || this.modal.querySelector('.jc-modal__actions');
        this.modalLoading = this.modal.querySelector('.jc-modal__loading');
        this.modalContainer = this.modal.querySelector('.jc-modal__container');
        this.modalOverlay = this.modal.querySelector('.jc-modal__overlay');
        this.closeButton = this.modal.querySelector('.jc-modal__close');

        // Apply config
        if (this.config.className) this.modalContainer.classList.add(this.config.className);
        if (!this.config.closable) this.closeButton.style.display = 'none';
        if (!this.config.backdrop) this.modalOverlay.style.display = 'none';

        this.setSize(this.config.size);
        this.setupEvents();
        if (this.config.draggable) this.setupDrag();
        this.bindTriggers();
    }

    setupEvents() {
        this.modal.addEventListener('click', (e) => {
            if ((e.target.closest('.jc-modal__close') || 
                (e.target.classList.contains('jc-modal__overlay') && this.config.closable))) {
                this.close();
            }
        });

        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape' && this.isOpen && this.config.closable) this.close();
        });
    }

    setupDrag() {
        this.modalContainer.classList.add('jc-modal__container--draggable');
        const header = this.modalTitle || this.modalContainer;

        header.addEventListener('mousedown', (e) => {
            if (e.button !== 0) return;
            
            this.isDragging = true;
            this.dragStartX = e.clientX;
            this.dragStartY = e.clientY;
            
            const rect = this.modalContainer.getBoundingClientRect();
            this.dragOffsetX = this.dragStartX - rect.left;
            this.dragOffsetY = this.dragStartY - rect.top;
            
            document.addEventListener('mousemove', this.handleDragMove);
            document.addEventListener('mouseup', this.handleDragEnd);
        });
    }

    handleDragMove = (e) => {
        if (!this.isDragging) return;
        
        const x = e.clientX - this.dragOffsetX;
        const y = e.clientY - this.dragOffsetY;
        
        this.modalContainer.style.left = `${x}px`;
        this.modalContainer.style.top = `${y}px`;
        this.modalContainer.style.margin = '0';
        this.modalContainer.style.transform = 'none';
    };

    handleDragEnd = () => {
        this.isDragging = false;
        document.removeEventListener('mousemove', this.handleDragMove);
        document.removeEventListener('mouseup', this.handleDragEnd);
    };

    bindTriggers() {
        document.querySelectorAll(`[data-modal-target="#${this.modal.id}"]`).forEach(trigger => {
            trigger.addEventListener('click', () => this.openFromTrigger(trigger));
        });
    }

    openFromTrigger(trigger) {
        const title = trigger.getAttribute('data-modal-title') || this.config.title;
        const content = trigger.getAttribute('data-modal-content') || this.config.content;
        const buttons = JSON.parse(trigger.getAttribute('data-modal-buttons') || '[]');
        const size = trigger.getAttribute('data-modal-size') || this.config.size;
        const draggable = trigger.hasAttribute('data-modal-draggable') || this.config.draggable;

        this.open({
            title,
            content,
            buttons: buttons.length ? buttons.map(btn => ({
                text: btn.text,
                action: () => {
                    if (btn.action && typeof window[btn.action] === 'function') {
                        window[btn.action]();
                    }
                },
                type: btn.type || 'default',
                close: btn.close !== false
            })) : this.config.buttons,
            size,
            draggable,
            onOpen: this.config.onOpen,
            onClose: this.config.onClose
        });
    }

    open(config = {}) {
        return new Promise((resolve) => {
            if (this.isOpen) {
                this.close().then(() => this._open(config, resolve));
            } else {
                this._open(config, resolve);
            }
        });
    }

    _open(config, resolve) {
        const mergedConfig = { ...this.config, ...config };
        
        this.setTitle(mergedConfig.title);
        this.setContent(mergedConfig.content);
        this.setSize(mergedConfig.size);
        this.setAnimation(mergedConfig.animation);
        
        if (mergedConfig.draggable !== this.config.draggable) {
            if (mergedConfig.draggable) {
                this.setupDrag();
            } else {
                this.modalContainer.classList.remove('jc-modal__container--draggable');
                this.modalContainer.style.left = '';
                this.modalContainer.style.top = '';
                this.modalContainer.style.margin = '';
            }
        }
        
        this.modalButtons.innerHTML = mergedConfig.buttons.map(btn => `
            <button class="jc-modal__button ${btn.type ? `jc-modal__button--${btn.type}` : ''}">
                ${btn.text}
            </button>
        `).join('');
        
        this.modalButtons.querySelectorAll('.jc-modal__button').forEach((btn, index) => {
            btn.addEventListener('click', () => {
                mergedConfig.buttons[index].action?.();
                if (mergedConfig.buttons[index].close !== false) this.close();
            });
        });
        
        if (mergedConfig.form) this.setForm(mergedConfig.form);
        
        this.modal.classList.add('jc-modal--active');
        document.body.style.overflow = 'hidden';
        this.isOpen = true;
        
        this.triggerEvent('open');
        mergedConfig.onOpen?.();
        resolve(this);
    }

    close() {
        return new Promise((resolve) => {
            if (!this.isOpen) return resolve();
            
            this.modal.classList.add('jc-modal--closing');
            
            setTimeout(() => {
                this.modal.classList.remove('jc-modal--closing');
                this.modal.classList.remove('jc-modal--active');
                document.body.style.overflow = '';
                this.isOpen = false;
                
                this.triggerEvent('close');
                this.config.onClose?.();
                resolve(this);
            }, 300);
        });
    }

    setTitle(title) {
        this.modalTitle.textContent = title;
        return this;
    }

    setContent(content) {
        if (typeof content === 'string') {
            this.modalContent.innerHTML = content;
        } else if (content instanceof HTMLElement) {
            this.modalContent.innerHTML = '';
            this.modalContent.appendChild(content);
        }
        return this;
    }

    setForm(formConfig) {
        const form = document.createElement('form');
        form.className = 'jc-modal__form';
        
        formConfig.fields.forEach(field => {
            const group = document.createElement('div');
            group.className = 'jc-modal__form-group';
            
            const label = document.createElement('label');
            label.className = 'jc-modal__form-label';
            label.textContent = field.label;
            label.htmlFor = field.id;
            
            let input;
            if (field.type === 'textarea') {
                input = document.createElement('textarea');
                input.rows = field.rows || 3;
            } else {
                input = document.createElement('input');
                input.type = field.type || 'text';
            }
            
            input.id = field.id;
            input.className = 'jc-modal__form-input';
            input.placeholder = field.placeholder || '';
            input.value = field.value || '';
            input.required = field.required || false;
            
            group.appendChild(label);
            group.appendChild(input);
            form.appendChild(group);
        });
        
        if (formConfig.submit) {
            const submitBtn = document.createElement('button');
            submitBtn.type = 'submit';
            submitBtn.className = `jc-modal__button ${formConfig.submit.type ? `jc-modal__button--${formConfig.submit.type}` : ''}`;
            submitBtn.textContent = formConfig.submit.text || '提交';
            form.appendChild(submitBtn);
        }
        
        form.addEventListener('submit', (e) => {
            e.preventDefault();
            const formData = {};
            formConfig.fields.forEach(field => {
                formData[field.id] = form.querySelector(`#${field.id}`).value;
            });
            
            if (formConfig.onSubmit) formConfig.onSubmit(formData);
            if (formConfig.closeOnSubmit !== false) this.close();
        });
        
        this.modalContent.innerHTML = '';
        this.modalContent.appendChild(form);
        return this;
    }

    addButton(text, action, type = 'default', close = true) {
        const button = document.createElement('button');
        button.className = `jc-modal__button ${type ? `jc-modal__button--${type}` : ''}`;
        button.textContent = text;
        button.addEventListener('click', () => {
            action?.();
            if (close) this.close();
        });
        this.modalButtons.appendChild(button);
        return this;
    }

    setSize(size) {
        this.modalContainer.classList.remove(
            'jc-modal__container--small',
            'jc-modal__container--medium',
            'jc-modal__container--large',
            'jc-modal__container--fullscreen'
        );
        
        switch (size) {
            case 'small': this.modalContainer.classList.add('jc-modal__container--small'); break;
            case 'large': this.modalContainer.classList.add('jc-modal__container--large'); break;
            case 'fullscreen': this.modalContainer.classList.add('jc-modal__container--fullscreen'); break;
        }
        
        this.config.size = size;
        return this;
    }

    setAnimation(animation) {
        this.modalContainer.style.animation = '';
        
        switch (animation) {
            case 'slide-up': this.modalContainer.style.animation = 'fadeInUp 0.5s ease-out forwards'; break;
            case 'slide-down': this.modalContainer.style.animation = 'fadeOutDown 0.5s ease-out reverse forwards'; break;
            case 'slide-left': this.modalContainer.style.animation = 'slideInLeft 0.5s ease-out forwards'; break;
            case 'slide-right': this.modalContainer.style.animation = 'slideInRight 0.5s ease-out forwards'; break;
        }
        
        this.config.animation = animation;
        return this;
    }

    showLoading() {
        this.modalLoading.classList.add('jc-modal__loading--active');
        return this;
    }

    hideLoading() {
        this.modalLoading.classList.remove('jc-modal__loading--active');
        return this;
    }

    on(event, callback) {
        if (!this.events[event]) this.events[event] = [];
        this.events[event].push(callback);
        return this;
    }

    triggerEvent(event) {
        if (this.events[event]) {
            this.events[event].forEach(callback => callback(this));
        }
    }

    registerMethod(name, fn) {
        this[name] = fn.bind(this);
        return this;
    }

    destroy() {
        this.close().then(() => {
            this.modal.remove();
            JCuPupw.instances.delete(this.id);
        });
    }

    static create(config = {}) {
        return new JCuPupw(null, config);
    }

    static getAll() {
        return Array.from(JCuPupw.instances.values());
    }

    static closeAll() {
        JCuPupw.instances.forEach(instance => instance.close());
    }
}

// Auto-init modals
document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('.jc-modal').forEach(modal => {
        new JCuPupw(modal);
    });
});

// Toast Notification System
class JCuToast {
    static queue = [];
    static defaults = {
        duration: 3000,
        position: 'top-right',
        closable: true,
        type: 'info',
        message: '',
        animation: 'fade',
        queue: true
    };

    static positions = {
        'top-center': { top: '20px', left: '50%', transform: 'translateX(-50%)' },
        'bottom-center': { bottom: '20px', left: '50%', transform: 'translateX(-50%)' },
        'top-right': { top: '20px', right: '20px' },
        'top-left': { top: '20px', left: '20px' },
        'bottom-right': { bottom: '20px', right: '20px' },
        'bottom-left': { bottom: '20px', left: '20px' }
    };

    constructor(config) {
        this.config = { ...JCuToast.defaults, ...config };
        this.toast = this.createToast();
        this.timeoutId = null;
        
        if (this.config.queue) {
            JCuToast.queue.push(this);
            this.processQueue();
        } else {
            this.show();
        }
    }

    createToast() {
        const toast = document.createElement('div');
        toast.className = `jc-toast jc-toast--${this.config.type}`;
        toast.setAttribute('role', 'alert');
        
        const iconMap = {
            success: '✓',
            error: '⚠',
            warning: '!',
            info: 'i'
        };
        
        toast.innerHTML = `
            <span class="jc-toast__icon">${iconMap[this.config.type] || ''}</span>
            <div class="jc-toast__content">${this.config.message}</div>
            ${this.config.closable ? '<button class="jc-toast__close" aria-label="Close">&times;</button>' : ''}
        `;
        
        Object.assign(toast.style, JCuToast.positions[this.config.position]);
        return toast;
    }

    show() {
        document.body.appendChild(this.toast);
        void this.toast.offsetWidth;
        this.toast.classList.add('jc-toast--active');
        
        if (this.config.duration > 0) {
            this.timeoutId = setTimeout(() => this.close(), this.config.duration);
        }
        
        if (this.config.closable) {
            this.toast.querySelector('.jc-toast__close').addEventListener('click', () => this.close());
        }
    }

    close() {
        clearTimeout(this.timeoutId);
        this.toast.classList.remove('jc-toast--active');
        
        setTimeout(() => {
            this.toast.remove();
            if (this.config.queue) {
                JCuToast.queue = JCuToast.queue.filter(t => t !== this);
                this.processQueue();
            }
        }, 300);
    }

    processQueue() {
        if (JCuToast.queue.length > 0 && JCuToast.queue[0] === this) {
            this.show();
        }
    }

    static success(message, options) {
        return new JCuToast({ ...options, type: 'success', message });
    }

    static error(message, options) {
        return new JCuToast({ ...options, type: 'error', message });
    }

    static warning(message, options) {
        return new JCuToast({ ...options, type: 'warning', message });
    }

    static info(message, options) {
        return new JCuToast({ ...options, type: 'info', message });
    }

    static clearAll() {
        document.querySelectorAll('.jc-toast').forEach(toast => {
            toast.classList.remove('jc-toast--active');
            setTimeout(() => toast.remove(), 300);
        });
        JCuToast.queue = [];
    }
}

// Global access
window.JCuPupw = JCuPupw;
window.JCuToast = JCuToast;

// Initialize default instance
const jcModal = new JCuPupw('#jcModal');